/*
 * @Author: 葛文杰
 * @Date: 2021/1/29 10:26
 * @Description: egg service 数据源
 */

'use strict';

const Service = require('egg').Service;
const DataSourceConfigProxy = require('../proxy/dataSourceConfigProxy');
const DataSourceInterfaceParamProxy = require('../proxy/dataSourceInterfaceParamProxy');
const DataSourceFieldProxy = require('../proxy/dataSourceFieldProxy');
const EnumerationManageProxy = require('../proxy/enumerationManageProxy');
const { buildTableData, getEnumerationInfoByIdAndType } = require('../util/utils');
const {
    IS_DELETE,
    IS_ENABLE,
    IS_NOT_ENABLE,
    DATA_SOURCE_STATUS,
    ENUMERATION_NAME_FIELD,
    ENUMERATION_VALUE_FIELD
} = require('../util/common');
const { PULL_TIME_OPTION_ARRAY } = require('../util/pullTimeOptions');

/**
 * 获取数据源推送频率
 * @param dataSourcePullRate
 * @param dataSourcePullDay
 */
function getDataSourcePullRateLabel(dataSourcePullRate, dataSourcePullDay) {
    let dataSourcePullRateLabel;
    let dataSourcePullDayLabel;
    let dataSourcePullDayArray;
    for (let { value, label, children } of PULL_TIME_OPTION_ARRAY) {
        if (dataSourcePullRate === value) {
            dataSourcePullRateLabel = label;
            dataSourcePullDayArray = children;
            break;
        }
    }
    for (let { value, label } of dataSourcePullDayArray) {
        if (dataSourcePullDay === value) {
            dataSourcePullDayLabel = label;
            break;
        }
    }
    let dataSourcePullRateName = `${dataSourcePullRateLabel} / ${dataSourcePullDayLabel}`;
    return dataSourcePullRateName;
}

/**
 * 构造数据源配置列表
 */
async function constructorDataSourceConfigList(conn, dataSourceConfigList) {
    let dataSourceConfigArray = [];
    for (let dataSourceConfigInfo of dataSourceConfigList) {
        dataSourceConfigInfo = await constructorDataSourceConfigInfo(conn, dataSourceConfigInfo);
        dataSourceConfigArray.push(dataSourceConfigInfo);
    }
    return dataSourceConfigArray;
}

/**
 * 构造数据源配置
 */
async function constructorDataSourceConfigInfo(conn, dataSourceConfigInfo) {
    let { dataSourcePullType, dataSourceStatus, dataSourcePullRate, dataSourcePullDay } = dataSourceConfigInfo;
    dataSourceConfigInfo.dataSourcePullTypeLabel =
      await getEnumerationInfoByIdAndType(conn, dataSourcePullType, ENUMERATION_NAME_FIELD);
    dataSourceConfigInfo.dataSourceStatusLabel =
      await getEnumerationInfoByIdAndType(conn, dataSourceStatus, ENUMERATION_NAME_FIELD);
    dataSourceConfigInfo.dataSourcePullRateLabel =
      getDataSourcePullRateLabel(dataSourcePullRate, dataSourcePullDay);
    dataSourceConfigInfo.dataSourceStatusValue =
      await getEnumerationInfoByIdAndType(conn, dataSourceStatus, ENUMERATION_VALUE_FIELD);
    return dataSourceConfigInfo;
}

class DataSourceConfig extends Service {

    /**
     * 获取数据源配置列表
     */
    async getDataSourceConfigList(dataSourceConfigCondition) {
        const conn = await this.app.mysql.beginTransaction();
        try {
            let { pageNo, pageSize, ...otherCondition } = dataSourceConfigCondition;
            otherCondition.pageNo = parseInt(pageNo);
            otherCondition.pageSize = parseInt(pageSize);
            let dataSourceConfigList = await DataSourceConfigProxy.getDataSourceConfigList(conn, otherCondition);
            let total = await DataSourceConfigProxy.getDataSourceConfigTotal(conn, otherCondition);
            dataSourceConfigList = await constructorDataSourceConfigList(conn, dataSourceConfigList);
            await conn.commit(); // 提交事务
            return buildTableData(dataSourceConfigList, total, pageNo, pageSize);
        } catch (err) {
            await conn.rollback(); // 一定记得捕获异常后回滚事务！！
            throw err;
        }
    }

    /**
     * 获取数据源配置
     * @return dataSourceConfig
     */
    async getDataSourceConfigById(dataSourceConfigCondition) {
        const conn = await this.app.mysql.beginTransaction(); // 初始化事务
        try {
            let { dataSourceConfigId } = dataSourceConfigCondition;
            let condition = {
                id: dataSourceConfigId
            };
            let dataSourceConfig = await DataSourceConfigProxy.getDataSourceConfigById(conn, condition);
            let dataSourceConfigInfo = {};
            if (dataSourceConfig) {
                dataSourceConfigInfo = constructorDataSourceConfigInfo(conn, dataSourceConfig);
            }
            await conn.commit(); // 提交事务
            return dataSourceConfigInfo;
        } catch (err) {
            await conn.rollback(); // 一定记得捕获异常后回滚事务！！
            throw err;
        }
    }

    /**
     * 保存数据源配置
     * @return {Promise<void>}
     */
    // TODO 创建人
    async insertDataSourceConfigInfo(dataSourceConfigCondition) {
        const conn = await this.app.mysql.beginTransaction(); // 初始化事务
        try {
            let { tempId, ...dataSourceConfigInfo } = dataSourceConfigCondition;
            let dataSourceConfig = {
                ...dataSourceConfigInfo,
                isDelete: IS_NOT_ENABLE,
                createUser: 1,
            };
            const result = await DataSourceConfigProxy.insertDataSourceConfigInfo(conn, dataSourceConfig);
            let { insertId } = result;
            let value = {
                dataSourceConfigId: insertId
            };
            let condition = {
                where: {
                    dataSourceConfigId: tempId,
                }
            };
            // 更新临时Id
            await DataSourceInterfaceParamProxy.updateDataSourceConfigTempIdById(conn, value, condition);
            await DataSourceFieldProxy.updateDataSourceConfigTempIdById(conn, value, condition);
            await conn.commit();
            return result;
        } catch (err) {
            await conn.rollback();
            throw err;
        }
    }

    /**
     * 修改数据源配置
     * @return {Promise<void>}
     */
    async updateDataSourceConfig(dataSourceConfigCondition) {
        const conn = await this.app.mysql.beginTransaction(); // 初始化事务
        try {
            const result = await DataSourceConfigProxy.updateDataSourceConfig(conn, dataSourceConfigCondition);
            await conn.commit();
            return result;
        } catch (err) {
            await conn.rollback();
            throw err;
        }
    }


    /**
     * 逻辑删除数据源配置
     * @return {Promise<void>}
     */
    async deleteDataSourceConfigById(dataSourceConfigId) {
        const conn = await this.app.mysql.beginTransaction(); // 初始化事务
        try {
            let baseCondition = {
                id: dataSourceConfigId,
            };
            let condition = {
                ...baseCondition,
                isDelete: IS_DELETE
            };
            const dataSourceConfigInfo = await DataSourceConfigProxy.getDataSourceConfigById(conn, baseCondition);
            let { dataSourceStatus } = dataSourceConfigInfo;
            let enableValue = await getEnumerationFieldValueById(conn, DATA_SOURCE_STATUS, dataSourceStatus, ENUMERATION_VALUE_FIELD);
            let result;
            if (enableValue === `${IS_NOT_ENABLE}`) {
                result = await DataSourceConfigProxy.updateDataSourceConfig(conn, condition);
            } else {
                result = {
                    isEnable: true
                };
            }
            let otherCondition = {
                dataSourceConfigId
            };
            await DataSourceInterfaceParamProxy.deleteInterfaceParamById(conn, otherCondition);
            await DataSourceFieldProxy.deleteFieldInfoById(conn, otherCondition);
            await conn.commit();
            return result;
        } catch (err) {
            await conn.rollback();
            throw err;
        }
    }

    /**
     * 启停用数据源
     * @param dataSourceConfigCondition
     * @return {Promise<void>}
     */
    async changeDataSourceConfigEnable(dataSourceConfigCondition) {
        const conn = await this.app.mysql.beginTransaction(); // 初始化事务
        const { dataSourceConfigId, dataSourceStatus } = dataSourceConfigCondition;
        const changeEnable = dataSourceStatus === `${IS_ENABLE}` ? IS_NOT_ENABLE : IS_ENABLE; // 取反
        try {
            let enumerationCondition = {
                enumerationType: DATA_SOURCE_STATUS,
                enumerationValue: changeEnable
            };
            let enumerationInfo = await EnumerationManageProxy.getEnumerationInfoByValue(conn, enumerationCondition);
            let { id: currentDataSourceStatus } = enumerationInfo;
            let condition = {
                id: dataSourceConfigId,
                dataSourceStatus: currentDataSourceStatus
            };
            const result = await DataSourceConfigProxy.updateDataSourceConfig(conn, condition);
            await conn.commit();
            return result;
        } catch (err) {
            await conn.rollback();
            throw err;
        }
    }
}

module.exports = DataSourceConfig;
